<template>
	<el-form ref="formRef" class="yd-form" :model="formModel" label-suffix="：" label-width="130px" :size="size" :inline="true" v-bind="config">
		<el-row>
			<!--不循环row，直接循环col，放不下会自动往下换行。-->
			<!-- <block> </block> -->
			<el-col v-for="(option, index) in formOptions" :key="'form_' + index" :span="option.show ? option.span || 6 : 0" :style="option.style || {}">
				<!--  -->
				<el-form-item v-if="option.show" :label="option.label" :prop="option.prop" :rules="option.rules">
					<el-date-picker
						v-if="option.type == 'date-picker'"
						v-model="dateRange"
						:disabled-date="DisabledDate"
						:shortcuts="shortcutsOptions"
						:editable="false"
						:clearable="false"
						v-bind="option.attrs"
						:type="option.dateType"
						range-separator="至"
						start-placeholder="开始日期"
						end-placeholder="结束日期"
						value-format="YYYY-MM-DD HH:mm:00"
						class="yd-form-item"
						@change="($event:any) => onDateChange($event, option)"
					>
					</el-date-picker>
					<!-- select组件  没有开启remote远程搜索-->
					<el-select
						v-else-if="(option.type === 'select' || option.type === 'group-select') && option.attrs?.remote !== true"
						:ref="'select_' + index"
						v-model="formModel[option.prop]"
						class="yd-form-item"
						:clearable="true"
						v-bind="option.attrs"
						collapse-tags
						collapse-tags-tooltip
						remote-show-suffix
						:loading="option.attrs?.loading"
						filterable
						:filter-method="(query:string) => onSelectFilter(query, option, index)"
						remote
						:placeholder="option.placeholder || '请选择' + option.label"
						@change="onSelectChange($event, option, index)"
					>
						<!-- <el-option v-if="option?.attrs.multiple" label="全部" value=""> -->
						<!-- 全选 -->
						<div v-if="option.attrs?.multiple" class="select-all">
							<el-checkbox
								v-model="option.selectAll"
								label="全选"
								size="small"
								:indeterminate="option?.attrs.indeterminate"
								@change="onCheckboxChange($event, option)"
							/>
						</div>
						<!-- </el-option> -->
						<component
							:is="child.children ? 'el-option-group' : 'el-option'"
							v-for="(child, i) in option.children"
							:key="'option_' + i"
							:label="option.selectLabel ? child[option.selectLabel] : child.label"
							:value="option.selectKey ? child[option.selectKey] : child.value"
							@click.prevent=""
							@mousedown.prevent=""
						>
							<component
								:is="'el-option'"
								v-for="(subChild, ind) in child.children as Array<Record<string, unknown>>"
								:key="'suboption_' + ind"
								:label="option.selectLabel ? subChild[option.selectLabel] : subChild.label"
								:value="option.selectKey ? subChild[option.selectKey] : subChild.value"
								:style="{ display: subChild.display === 'none' ? 'none' : 'list-item' }"
							/>
						</component>
					</el-select>
					<!--  select组件 开启remote远程搜索 -->
					<el-select
						v-else-if="(option.type === 'select' || option.type === 'group-select') && option.attrs?.remote === true"
						:ref="'select_' + index"
						v-model="formModel[option.prop]"
						class="yd-form-item"
						:clearable="true"
						v-bind="option.attrs"
						collapse-tags
						:loading="option.attrs?.loading"
						filterable
						remote
						:filter-method="(query:string) => onSelectFilter(query, option, index)"
						:remote-method="(query:string) => onRemoteSelectFilter (query, option, index)"
						:placeholder="option.placeholder || '请选择' + option.label"
						@change="onSelectChange($event, option, index)"
					>
						<!-- <el-option v-if="option?.attrs.multiple" label="全部" value=""> -->
						<!-- 全选 -->
						<div v-if="option.attrs?.multiple" class="select-all">
							<el-checkbox
								v-model="option.selectAll"
								label="全选"
								size="small"
								:indeterminate="option?.attrs.indeterminate"
								@change="onCheckboxChange($event, option)"
							/>
						</div>
						<!-- </el-option> -->
						<component
							:is="child.children ? 'el-option-group' : 'el-option'"
							v-for="(child, i) in option.children"
							:key="'option_' + i"
							:label="option.selectLabel ? child[option.selectLabel] : child.label"
							:value="option.selectKey ? child[option.selectKey] : child.value"
							@click.prevent=""
							@mousedown.prevent=""
						>
							<component
								:is="'el-option'"
								v-for="(subChild, ind) in child.children as Array<Record<string, unknown>>"
								:key="'suboption_' + ind"
								:label="option.selectLabel ? subChild[option.selectLabel] : subChild.label"
								:value="option.selectKey ? subChild[option.selectKey] : subChild.value"
								:style="{ display: subChild.display === 'none' ? 'none' : 'list-item' }"
							/>
						</component>
					</el-select>
					<!-- upload上传组件 -->
					<el-upload
						v-else-if="option.type === 'upload'"
						class="upload-wraper"
						:action="option.attrs?.action"
						:show-file-list="false"
						:on-success="(event:any) => onAvatarSuccess(event, option)"
						:on-error="(event:any) => onAvatarFail(event, option)"
						:before-upload="(event:any) => onBeforeAvatarUpload(event, option)"
						drag
						v-bind="option.attrs"
					>
						<!-- 插槽 -->
						<template v-if="option.slots?.default" #default>
							<RenderDom :v-node="option.slots?.default?.render(option)"></RenderDom>
						</template>
						<!-- 默认样式 -->
						<div v-if="!option.slots?.default">
							<div v-if="uploadImageUrl">
								<el-image class="avatar" :src="uploadImageUrl" fit="contain"></el-image>
							</div>
							<div v-else>
								<el-icon><Upload /></el-icon>
								<div>将文件拖到此处，或<a class="color-primary">点击上传</a></div>
							</div>
						</div>
						<template v-if="!option.slots?.default" #tip>
							<div class="el-upload__tip">只能上传 jpg/png 文件，且不超过 500kb</div>
						</template>
					</el-upload>

					<!-- checkboxgruop、radiogroup -->
					<component
						:is="`el-${option.type}`"
						v-else-if="option.children && (option.type === 'checkbox-group' || option.type === 'radio-group')"
						v-model="formModel[option.prop]"
						v-bind="option.attrs"
						class="yd-form-item"
						@change="onChange($event, option)"
					>
						<component
							:is="option.type === 'checkbox-group' ? 'el-checkbox' : 'el-radio'"
							v-for="(child, i) in option.children"
							:key="i"
							:label="child.value"
						>
							{{ child.label }}
						</component>
					</component>
					<!-- checkbox、radio -->
					<component
						:is="option.type === 'checkbox' ? 'el-checkbox' : 'el-radio'"
						v-else-if="option.children && (option.type === 'checkbox' || option.type === 'radio')"
						v-for="(child, i) in option.children"
						:key="i"
						v-model="formModel[option.prop]"
						class="yd-form-item"
						@change="onChange($event, option)"
					>
						{{ child.label }}
					</component>

					<!--没有嵌套的组件、input、inputnumber等-->
					<component
						:is="`el-${option.type}`"
						v-else
						v-model="formModel[option.prop]"
						:clearable="true"
						v-bind="option.attrs"
						:placeholder="option.placeholder || '请输入' + option.label"
						class="yd-form-item"
						@change="onChange($event, option)"
						@input="onInput($event, option.prop)"
					>
						<template v-for="(item, key) in option.slots" :key="key" #[key]="{}">
							<RenderDom :v-node="item && item.render(item)"></RenderDom>
						</template>
					</component>
				</el-form-item>
			</el-col>

			<!-- 按钮 -->
			<div v-if="btnList?.length" class="yd-form-btn-group">
				<el-button
					v-for="(btn, index) in btnList"
					:key="btn.type + index"
					class="yd-form-btn"
					:style="btn.style"
					:type="btn.type"
					@click="onBtnClick(btn)"
					>{{ btn.text }}</el-button
				>
			</div>
			<!-- 表单尾部插槽，多用于按钮 -->
			<slot name="form-btn" :model="formModel"></slot>
		</el-row>
		<!-- 表单底部插槽 -->
		<slot name="form-footer" :model="formModel"></slot>
	</el-form>
</template>

<script lang="tsx" setup>
import {
	ref,
	reactive,
	onBeforeMount,
	computed,
	onMounted,
	watch,
	onActivated,
	toRaw,
	toRefs,
	getCurrentInstance,
	nextTick,
	onDeactivated,
} from 'vue';
import { useRoute } from 'vue-router';
import { Upload } from '@element-plus/icons-vue';
import RenderDom from './render.jsx';
import * as searchOption from '@/api/search/searchOptions';
import { deepClone, isSameObect } from '@/utils/common';
import type { FormInstance } from 'element-plus';
import useSelect from './useSelect';
import useDate from './useDate';
import useIsParamsChange from './useIsParamsChange';
import { number } from 'echarts/core.js';
import { Options } from '@antv/x6/lib/graph/options';
const props = withDefaults(
	defineProps<{
		model: FormModelType;
		options: BaseOptionType[];
		btns?: Array<BtnType>;
		config?: Record<string, string | number | boolean>;
		size?: 'small' | 'default' | 'large';
	}>(),
	{
		btns: () => {
			return [];
		},
		config: () => {
			return {};
		},
		options: () => {
			return [];
		},
		model: () => {
			return {};
		},
		size: 'default',
	}
);

const emits = defineEmits<{
	(e: 'formInit', formModel: FormModelType, formOptions?: any): void;
	(e: 'change', option: BaseOptionType, value?: any, statusValue?: any): void;
	(e: 'search'): void;
}>();

const instance = getCurrentInstance();
const proxy = instance?.proxy;

const formRef = ref<FormInstance>();
const route = useRoute();

// const formModel = ref(props.model);
const formModel = computed(() => {
	return props.model;
});

const dateRange = ref<any[]>();

// formModel的深拷贝对象
const cloneFormModel = ref<FormModelType>({});
// const cloneFormModel.value = reactive<FormModelType>({});

// 用来存储表单初始化后的值
const initFormModel = ref<FormModelType>({});
const initCloneFormModel = ref<FormModelType>({});

// 表单项字典
const formOptions = computed(() => {
	props.options.forEach((option: BaseOptionType) => {
		// 如果没有设置show字段。默认为true
		if (typeof option.showCascader === 'object' && option.show === undefined) {
			initToggleFormItem(option);
		} else {
			option.show = option.show === undefined ? true : option.show;
		}
	});
	return props.options;
});

// formOptions的深拷贝对象
const cloneFormOptions = ref<BaseOptionType[]>([]);

// 按钮字典
const btnList = computed(() => {
	return props.btns;
});

//   upload组件的url
const uploadImageUrl = ref<string>('');
let useSelectStore: any = null;

let pageInit = ref(true);

const { shortcutsOptions, shortcutsOptionsFilter, initDateValue, timeRangeValueChange } = useDate(formModel, dateRange);
const { isParamsChange } = useIsParamsChange(route.query);

// 修改cloneForm
// watch(
// 	() => formModel.value,
// 	(newval) => {
// 		// 修改cloneFormModel的值
// 		for (let key in newval) {
// 			if (newval[key] && JSON.stringify(newval[key]) === '[""]') {
// 				cloneFormModel.value[key] = [];
// 			} else {
// 				cloneFormModel.value[key] = newval[key];
// 			}
// 		}
// 	},
// 	{
// 		deep: true,
// 	}
// );
// 修改时间选择器的值
watch(
	() => formModel.value.startTime,
	(newval) => {
		// 如果是date-picker,触发修改方法
		let data = formModel.value;
		if (newval) {
			let option = formOptions.value.find((opt: BaseOptionType) => opt.type === 'date-picker');
			if (option) {
				initDateValue(option, [data.startTime, data.endTime]);
			}
		}
	},
	{
		deep: true,
	}
);

const initToggleFormItem = (option: BaseOptionType) => {
	let showCascaderProp = option.showCascader!.prop;
	let showCascaderValue = option.showCascader!.showValue;
	watch(
		() => formModel.value[showCascaderProp],
		(value: any) => {
			// console.log('initToggleFormItem', value);
			if (value === showCascaderValue) {
				option.show = true;
			} else {
				option.show = false;
			}
		},
		{
			deep: true,
			immediate: true,
		}
	);
};

// 监听联动下拉框的改变
const initSelectChangeWatch = () => {
	props.options.forEach((option: BaseOptionType, index: number) => {
		// 如果没有设置show字段。默认为true
		if (option.type === 'select' && option.cascaders) {
			watch(
				() => formModel.value[option.prop],
				(newval) => {
					if (option.prop === 'businessCode') {
						console.log('watch--------------------------------------');
					}
					fetSetCacasders(option.cascaders!, newval);
				},
				{
					deep: true,
				}
			);
		}
	});
};
//

onBeforeMount(async () => {
	// 初始化表单数据
	initModel(formOptions.value, formModel.value);

	//
	initSelectChangeWatch();
	// 初始化数据字典
	await initOptions(formOptions.value);
	// 克隆表单项的数据
	cloneOptions();
	// clone
	//
	initFormModel.value = deepClone(formModel.value);
	// console.log('initForm(--------------', initFormModel.value);
	// initCloneFormModel.value = deepClone(cloneFormModel.value);
	// 初始化store
	initStore();
	//   表单初始化完成事件
	emits('formInit', formModel.value, formOptions.value);
});
onActivated(() => {
	let query = route.query;
	if (pageInit.value === false && isParamsChange(query)) {
		// console.log('页面打开');
		// 路由参数query有改变。去初始化表单
		initForm();
		nextTick(() => {
			emits('search');
		});
	}
	pageInit.value = false;
});
onDeactivated(() => {
	formOptions.value.forEach((opt: BaseOptionType) => {
		opt.firstLoad = true;
	});
});

// 将表单设置成初始值
function initForm() {
	formOptions.value.forEach((opt) => {
		if (opt.type === 'date-picker') {
			// 日期选择类型
			initDateValue(opt);
		} else if (opt.type === 'input') {
			// input等普通类型
			formModel.value[opt.prop] = '';
			cloneFormModel.value[opt.prop] = '';
		} else {
			// 有数据字典的类型
			if (opt.isInitValue !== false) {
				initValue(opt, opt.children);
			}
		}
	});
}

const initStore = () => {
	// 下拉框
	useSelectStore = useSelect(formOptions.value, cloneFormOptions.value, formModel.value);
	useSelectStore?.initSelectAll();
};

/**
 * methods 方法
 *
 */
// 初始化表单的model,如果没有初始值，就给他设置一个初始值
// 如果是多选。初始值设置成[];否则初始值"";
const initModel = (options: BaseOptionType[], model: FormModelType) => {
	options.forEach((option: BaseOptionType) => {
		if (option.type === 'date-picker') {
			// 日期选择类型
			// 初始化日期快捷选项
			shortcutsOptionsFilter(option.shortcutsKeys);
			// console.log('formModel.value[option.prop]', formModel.value[option.prop]);
			// 初始化日期的值
			let query: anyObj;
			try {
				query = JSON.parse(route.query.data as string);
			} catch (e) {
				query = route.query;
			}
			if (query.startTime && query.endTime) {
				// 有query
				initDateValue(option, [query.startTime, query.endTime]);
			} else if (model.startTime !== undefined && model.endTime !== undefined) {
				// 有默认值
				initDateValue(option, [model.startTime, model.endTime]);
			} else {
				// 没有默认值
				initDateValue(option);
			}
		} else if (option.type === 'checkbox-group') {
			model[option.prop] = [];
		} else if (option.type === 'radio-group') {
			model[option.prop] = '';
		} else if (model[option.prop] === undefined) {
			// form没有设置初始值才才给它初始化值
			model[option.prop] = option.attrs?.multiple === true ? [] : '';
			// cloneFormModel.value[option.prop] = option.attrs?.multiple === true ? [] : '';
		}
		if ('cascaderParam' in option) {
			onCascaderParamWatch(option);
		}
	});
	// console.log('initModel', formModel.value);
	// console.log('initModel', cloneFormModel.value);
};

// 检测到该参数值改变，去请求下拉框的字典

const onCascaderParamWatch = (option: BaseOptionType) => {
	const key = option.cascaderParam!.key;
	watch(
		() => option.cascaderParam?.data[key],
		async (value: any) => {
			if (value && option.api) {
				await fetSetOption(option, option.api.name, value, option.api.dataKey);
			}
		},
		{
			deep: true,
			immediate: true,
		}
	);
};
// 初始化select、checkbox等组件的 options，如果有传api过来的，就去请求数据回来;并初始化他的值
const initOptions = (options: BaseOptionType[]) => {
	let count = 0; //记录多少项初始化完成，count>= options的长度时表示初始化完成了
	return new Promise((resolve: (value: unknown) => void) => {
		options.forEach(async (option: BaseOptionType) => {
			option.firstLoad = true; //表示首次加载
			if (option.api) {
				// 有api的话，就去请求
				if (option.attrs?.remote) {
					// 远程搜索，初始化远程搜索的option
					option.children = [];
				} else {
					// 如果没有开启远程搜索才去初始化下拉
					if (option.isInitOption !== false) {
						// 设置了不需要初始化字典就不去请求
						let result = await fetSetOption(option, option.api.name, option.api.params, option.api.dataKey);
					}

					if (option.cascaders) {
						// 有级联的选择器
						await fetSetCacasders(option.cascaders, formModel.value[option.prop]);
					}
					// if (option.attrs?.multiple) {
					// 	// 有多选的话去初始化复选框的状态
					// 	updateSelectAllStatus(option);
					// }
				}
			} else if (option.children) {
				// 如果有children，拿children初始化值
				if (!formModel.value[option.prop] && option.isInitValue !== false) {
					// 当前没有值才去初始化值
					initValue(option, option.children);
				}

				if (option.cascaders) {
					// 有级联的选择器,请求完成count才加一
					await fetSetCacasders(option.cascaders, formModel.value[option.prop]);
				}
			}
			count++;
			// console.log('count----------', option.prop);
			if (count >= options.length) {
				resolve(null);
			}

			// console.log('count', count);
		});
	});
};

/**
 * 请求字典,并设置option的值
 * @param option 表单配置项
 * @param name 请求的名字需要在 /api/search/searchOption.ts定义该方法
 * @param params  请求参数
 * @param dataKey 返回数据的key，默认data,多层级时： data.records
 */
const fetSetOption = (option: BaseOptionType, name: string, params: any, dataKey = 'data') => {
	if (params === '' || params === null) return; //参数为空
	// if (fetchCount.value === undefined) {
	// 	fetchCount.value = 0;
	// }
	// fetchCount.value++;
	return new Promise((resolve) => {
		if ((searchOption as any)[name] instanceof Function === false) {
			console.error(`searchOption.${name}不是方法`);
			resolve('error');
		}
		(searchOption as any)
			[name](params)
			.then((res: ApiResponse) => {
				if (res.code === 0) {
					option.children = [];
					if (params?.isServerList) {
						option.children = res.data[0].serverList;
					} else if (params?.isRecords) {
						option.children = res.data.records;
					} else {
						let reg = /^[a-z0-9]+(\.[a-z0-9]+){0,}$/;
						if (!reg.test(dataKey)) {
							throw Error('dataKey的格式不正确!');
						}
						const keyArr = dataKey.split('.');
						// 数据可能是多层级的，循环取到对应的数据
						let result;
						// keyArr = ['data','record']
						keyArr.forEach((key: any) => {
							result = res[key];
							res = res[key]; // 每取一次值，都将res指向新的对象
						});

						option.children = result;
					}
					// 将数据拷贝到cloneOption
					cloneOptions();
					resolve(option.children);
					if (option.firstLoad) {
						// 第一次加载的话，判断需不需要初始化值

						console.log('timeout==============------------', formModel.value[option.prop]);
						if (valiDateNull(formModel.value[option.prop]) && option.isInitValue !== false) {
							// 当前没有值才去初始化值 ,可能初始化有值或者查询参数有传值过来;
							console.log('option.firstLoad==============------------11');
							initValue(option, option.children);
							// option.isInitValue = false;
						}
						option.firstLoad = false;
						useSelectStore?.initSelectAll();
						// console.log('option.firstLoad==============------------', formModel.value[option.prop]);
					} else {
						// 不是第一次加载的话。直接去初始化值
						initValue(option, option.children);
					}
					// resolve(option.children);
				} else {
					resolve('error');
					throw new Error(res.msg);
				}
			})
			.catch((err: Error) => {
				console.log(err);
				resolve(option.children);
			});
	}).finally(() => {
		// fetchCount.value--;
	});
};

// 请求并设置级联选择器的值

const fetSetCacasders = (cascaders: CascaderType[], params: any) => {
	// console.log('fetSetCacasders', params);
	return new Promise((resolve) => {
		cascaders.forEach(async (cascader: CascaderType) => {
			const option: BaseOptionType = formOptions.value.find((opt) => opt.prop === cascader.cascadersParams) as BaseOptionType;

			if (valiDateNull(params)) {
				// console.log('请求参数为空----');
				//清空联动的项
				clearValue(option.prop);
				resolve('scuess');
				return;
			}
			if (option) {
				try {
					//
					await fetSetOption(option, cascader.api.name, params, cascader.api.dataKey);
				} catch (error) {
					//请求失败，清空联动的项
					clearValue(option.prop);
				}
			} else {
				console.error('没有这个项', cascader.cascadersParams);
			}
			resolve('scuess');
		});
	});
};

/**
 * 清空表单项，及表单项数据
 * @param prop 表单项的key
 *
 *  */
const clearValue = (prop: string) => {
	console.log('clearvalue----------', prop);
	const option: BaseOptionType = formOptions.value.find((opt) => opt.prop === prop) as BaseOptionType;
	if (!option) {
		console.error('没有这个项', prop);
		return;
	}
	if (option.children instanceof Array) {
		option.children = [];
	}
	if (option.attrs?.multiple) {
		formModel.value[option.prop] = [];
		// cloneFormModel.value[option.prop] = [];
	} else {
		formModel.value[option.prop] = '';
		// cloneFormModel.value[option.prop] = '';
	}
};

// 初始化有数据字典的表单项值 单选的选择第一项，多选的不选
// checkbox和radio不需要
const initValue = (option: BaseOptionType, children?: any) => {
	if (option.prop === 'businessCode') {
		console.log('initvalue', option.prop);
	}
	// console.log(' initValue');
	if (option.type.indexOf('checkbox') > -1 || option.type.indexOf('radio') > -1) return;
	if (option.attrs?.multiple) {
		formModel.value[option.prop] = [];
		// cloneFormModel.value[option.prop] = [];
	} else {
		if (children instanceof Array && children[0]) {
			let value = children[0][option.selectKey] || children[0].value;
			formModel.value[option.prop] = value;
			// cloneFormModel.value[option.prop] = value;
		}
	}
};

// 更新全选各状态
// 有两组值，cloneFormModel.value[option.prop] 为实际选择的值；用于页面渲染；formModel.value[option.prop]为用于传给后台的值 formModel.value[option.prop]=[""]表示全选
// 选择的项长度为0时，复选框是没有选择的状态 cloneFormModel.value[option.prop] = [];
// 选择的项大于0 等于选项长度时，复选框为全选状态 小于选项长度时。复选框为"-"状态
// 复选框全选状态clooneformModel.value[option.prop]的值为所有选项的value值组成的数组
// 复选框没有选择状态、全选状态  formModel.value[option.prop] 的值都为 [""]
const updateSelectAllStatus = (option: BaseOptionType, index: number) => {
	useSelectStore?.updateSelectAllStatus(option, index);
};

const cloneOptions = () => {
	cloneFormOptions.value = deepClone(formOptions.value) as BaseOptionType[];
	useSelectStore?.updateOptions(formOptions.value, cloneFormOptions.value);
};

// 时间选择器禁止选择的范围
const DisabledDate = (time: Date) => {
	return time.getTime() > Date.now();
};

const valiDateNull = (o: any) => {
	if (o === null || o === undefined || o === '') return true;
	if (o instanceof Array) {
		if (o.length === 0 || o[0] === '' || o[0] === undefined) {
			return true;
		} else {
			return false;
		}
	}
	return false;
};

/**
 * event 事件
 */

const onInput = (e: Event, prop: string) => {
	// console.log('input', e);
};
const onChange = (value: any, option: BaseOptionType) => {
	// console.log('change', value);
	emits('change', option, value);
};
//select 组件改变事件
const onSelectChange = (value: any, option: BaseOptionType, index: number) => {
	// console.log(option, value, index);
	// console.log('selectchange', option.prop);
	// console.log('selectchange', value);

	if (option.cascaders) {
		// 有联动的项，需要重新请求
		// fetSetCacasders(option.cascaders, value);
	}
	if (option.attrs?.multiple) {
		// 有全选的，要更新复选框按钮状态,全选的值是[""]需要在该方法处理
		updateSelectAllStatus(option, index);
	} else {
		// 没有直接更新formModel的值
		formModel.value[option.prop] = value;
	}
	// 只支持全选或者单选，不可多选
	if (option.isAllOrSingle && value.length > 0) {
		if (value.length === 1) {
			formModel.value[option.prop] = value;
			emits('change', option, value, formModel.value[option.prop]);
			return;
		}
		let len: number | undefined | any = option.children && option.children?.length;
		if (!option.selectAll && value.length >= 1 && value.length < len - 1) {
			let newVal = value.splice(1);
			formModel.value[option.prop] = newVal;
		} else {
			let values = new Set(value);
			let arr: string[] = [];
			option.children?.forEach((item: any) => arr.push(item.value));
			let modelName = Array.from(new Set([...arr].filter((x: string) => !values.has(x))));
			formModel.value[option.prop] = modelName;
		}
		emits('change', option, value, formModel.value[option.prop]);
		return;
	}

	emits('change', option, value);
};

// 全选/取消全选的方法
// 复选框全选状态 clooneformModel.value[option.prop]的值为所有选项的value值组成的数组  formModel.value[option.prop] 的值都为 [""]
// 复选框没有选择状态 clooneformModel.value[option.prop]的值为[],formModel.value[option.prop] 的值为 [""]
//
const onToggleSelectAll = (option: BaseOptionType, children: OptionChidrenType[]) => {
	useSelectStore?.onToggleSelectAll(option, children);
	// 触发change事件
	emits('change', option);
};
// select的搜索过滤方法
// 要区分分组下拉和普通下拉
const onSelectFilter = (query: string, option: BaseOptionType, index: number) => {
	useSelectStore?.onSelectFilter(query, option, index);
};

// 远程搜索，需要开启了remote才会生效
const onRemoteSelectFilter = async (query: string, option: BaseOptionType, index: number) => {
	if (!option.attrs?.remote) return;
	useSelectStore?.onRemoteSelectFilter(query, option, index, fetSetOption);
};

//   下拉组件全选复选框值改变事件
const onCheckboxChange = (e: any, option: BaseOptionType) => {
	if (option.children instanceof Array) {
		onToggleSelectAll(option, option.children);
	}
};
// 日期选择器改变事件
const onDateChange = (value: any, option: BaseOptionType) => {
	timeRangeValueChange(option);
	emits('change', option, value);
};

// 表单尾部的按钮点击事件
const onBtnClick = (e: Record<string, any>) => {
	let validateResult = reactive<validateResultType>({
		valid: true,
		msg: [],
		form: formModel,
	});

	// 如果开启了表单校验，需要调用校验方法
	if (e.valid) {
		formRef.value?.validate((flag: any, msg: any) => {
			validateResult.valid = flag;
			if (!flag) {
				// 校验失败将失败信息传过去
				validateResult.msg = msg;
			}
		});
	}
	//   console.log("resuklt", result);
	e.handler && e.handler(validateResult);
};

// 上传组件上传之前
const onBeforeAvatarUpload = (e: any, option: BaseOptionType) => {
	console.log(111);
};
// 上传成功
const onAvatarSuccess = (e: Event, option: BaseOptionType) => {
	console.log(2222);
};
// 上传失败
const onAvatarFail = (e: any, option: BaseOptionType) => {
	console.log(33333);
};

/**
 * 以下是emit事件
 *
 */

// 表单校验
const validate = (cb: (flag: boolean, msg?: any) => void) => {
	formRef.value?.validate((flag: any, msg: any) => {
		cb(flag, msg);
	});
};

// 重置表单
const resetFields = () => {
	formRef.value?.resetFields();
};

/**
 * 设置某一项的字典
 * @prop key
 * @params 请求参数
 *  */
const setOptions = (prop: string, params: any) => {
	let option = formOptions.value.find((opt: BaseOptionType) => opt.prop === prop);
	if (option && option.api) {
		fetSetOption(option, option.api.name, params);
	}
};

/**
 * select、checkbox等组件获取选项的label值
 * @prop formModal的key
 */
const getLabel = (prop: string) => {
	const option: BaseOptionType | undefined = formOptions.value.find((opt) => opt.prop === prop);
	let value: any;
	let result = '';
	if (option === undefined) {
		throw Error('没有这项');
	}
	// if (option.type === 'select' || option.type === 'date-picker') {
	// 	value = cloneFormModel.value[prop];
	// } else {
	// 	value = formModel.value[prop];
	// }
	value = formModel.value[prop];
	// string ['ff','ff']
	option.children?.forEach((item) => {
		if (value instanceof Array) {
			if (value.indexOf(item.value) > -1) {
				result += item.label + ',';
			}
		} else {
			if (value === item.value) {
				result += item.label + ',';
			}
		}
	});
	result = result.slice(0, -1);

	return result;
};

defineExpose({
	formRef: formRef,
	resetFields: resetFields,
	validate: validate,
	setOptions: setOptions,
	getLabel: getLabel,
	clearValue: clearValue,
	cloneOptions: cloneOptions,
});
</script>
<style lang="scss" scoped>
.el-form-item {
	display: flex;
	flex: 1;
	// max-width: 400px;
}
.yd-form-item {
	flex: 1;
}
:deep(.el-form-item--default) {
	margin-bottom: 20px;
}
.el-form--inline .el-form-item {
}
.yd-form-btn {
	margin-right: 10px;
}
.select-all {
	margin: 0px 0px 6px 12px;
}
:deep(.upload-wraper .el-upload) {
	// border: 1px dashed #d9d9d9;
	// border-radius: 6px;
	// cursor: pointer;
	position: relative;
	overflow: hidden;
	// width: 178px;
	// height: 178px;
	// display: flex;
	// align-items: center;
	// justify-content: center;
}
:deep(.upload-wraper .el-upload:hover) {
	// border-color: #409eff;
}
.avatar-uploader-icon {
	font-size: 28px;
	color: #8c939d;
	// width: 178px;
	// height: 178px;
	// width: 100%;
	// height: 100%;
	line-height: 178px;
	text-align: center;
}
.avatar {
	width: 178px;

	// height: 178px;
	display: block;
}
:deep(.el-upload-dragger) {
	width: 240px;
	height: 120px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.yd-form-btn-group {
	display: flex;
	// align-items: center;
	// justify-self: ;
}
</style>
